package com.katesoft.scale4j.demo.services;

import com.katesoft.scale4j.demo.domain.Currency;
import com.katesoft.scale4j.demo.domain.ExchangeRate;
import com.katesoft.scale4j.log.Logger;
import com.katesoft.scale4j.log.LogFactory;
import com.katesoft.scale4j.persistent.client.LocalHibernateTemplate;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedReader;
import java.io.StringReader;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import static com.katesoft.scale4j.persistent.utils.DataAccessUtility.fetchFirstRowOrNull;

public class CurrencyExchangeRatesTasklet implements Tasklet
{
    private Logger logger = LogFactory.getLogger(getClass());
    private SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
    private RestTemplate template = new RestTemplate();
    private LocalHibernateTemplate hibernateTemplate;

    @SuppressWarnings({"unchecked"})
    @Override
    public RepeatStatus execute(StepContribution contribution,
                                final ChunkContext chunkContext)
    {
        ExecutionContext context = chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext();
        String date = context.containsKey("date") ?  context.getString("date") : sf.format(new Date());
        List<Currency> currencyList = hibernateTemplate.loadAll(Currency.class);
        for (Currency currency : currencyList) {
            logger.info("%s ***********************************************************************************************", currency.getCode());
            try {
                String s = template
                    .getForObject("http://currencies.apps.grandtrunk.net/getrate/{date}/{fromcode}/{tocode}", String.class, date, "USD", currency.getCode());
                logger.info("got %s for values = %s", s, Arrays.toString(new String[]{date, "USD", currency.getCode()}));
                BufferedReader reader = new BufferedReader(new StringReader(s));
                try {
                    String next;
                    while ((next = reader.readLine()) != null) {
                        ExchangeRate exchangeRate = new ExchangeRate();
                        exchangeRate.setCurrency(currency);
                        exchangeRate.setRate(new BigDecimal(next));
                        exchangeRate.setActualDate(sf.parse(date));
                        ExchangeRate existingRate =
                            (ExchangeRate) fetchFirstRowOrNull(hibernateTemplate.findByNamedQuery("exchange_rate.find_by_code", currency));
                        if (existingRate != null) {
                            existingRate.setRate(exchangeRate.getRate());
                            existingRate.setActualDate(sf.parse(date));
                            hibernateTemplate.update(existingRate);
                        }
                        else {
                            hibernateTemplate.save(exchangeRate);
                        }
                        hibernateTemplate.flush();
                    }
                }
                finally {
                    reader.close();
                }
            }
            catch (Exception e) {
                logger.warn(e);
            }
        }
        hibernateTemplate.flush();
        return RepeatStatus.FINISHED;
    }

    @Autowired
    @Required
    public void setHibernateTemplate(LocalHibernateTemplate hibernateTemplate)
    {
        this.hibernateTemplate = hibernateTemplate;
    }
}
